package com.twang.stock.task;

import com.alibaba.fastjson.JSONObject;
import com.jayway.jsonpath.JsonPath;
import com.twang.stock.common.http.HttpClientService;
import com.twang.stock.entity.*;
import com.twang.stock.mapper.KaiPanLaZhangTingInfoMapper;
import com.twang.stock.mapper.ZhangTingBanMapper;
import com.twang.stock.redis.RedisUtil;
import com.twang.stock.service.CompanyStockMinutesService;
import com.twang.stock.service.IndexService;
import com.twang.stock.service.ZhangTingBanService;
import com.twang.stock.service.impl.IndexServiceImpl;
import com.twang.stock.service.impl.ZhangTingBanServiceImpl;
import com.twang.stock.service.jinyan.CompanyCodeInfoService;
import com.twang.stock.task.old.BaseTask;
import com.twang.stock.threadPool.AsycTaskExecutorConfig;
import com.twang.stock.utils.date.HolidayCopy;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.assertj.core.util.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * URL：http://quote.eastmoney.com/ztb/detail#type=ztgc
 *
 * 数据URL=https://push2ex.eastmoney.com/getTopicZTPool?cb=callbackdata9103697&ut=7eea3edcaed734bea9cbfc24409ed989&dpt=wz.ztzt&Pageindex=0&pagesize=320&sort=fbt%3Aasc&date=20220304
 */
@Slf4j
@Component
public class ZhangTingBanTask extends BaseTask {

    private static String URL = "https://push2ex.eastmoney.com/getTopicZTPool?cb=callbackdata9103697&ut=7eea3edcaed734bea9cbfc24409ed989&dpt=wz.ztzt&Pageindex=0&pagesize=320&sort=fbt%3Aasc&date=";

    @Resource
    private ZhangTingBanMapper zhangTingBanMapper;

    @Autowired
    private RedisUtil redisUtil;


    @Autowired
    private CompanyCodeInfoService companyCodeInfoService;

    @Autowired
    private CompanyStockMinutesService companyStockMinutesService;

    @Autowired
    @Lazy
    private ZhangTingBanService zhangTingBanService;

    @Resource
    private KaiPanLaZhangTingInfoMapper kaiPanLaZhangTingInfoMapper;


    @Autowired
    @Lazy
    private IndexService indexService;



    @Autowired
    private AsycTaskExecutorConfig asycTaskExecutorConfig;

    @Scheduled(cron = "0 0/1 * * * ?")
    public void excute() {
        //判断时间
        if (!isWorkTradeTime()) {
            return;
        }


        asycTaskExecutorConfig.taskQueueExecutor().execute(() -> {
            try {
                try{
                    insertZhangTingBanData(null);
                }catch (Exception e){
                    log.error("涨停板查询失败：{}",e);
                }finally {
                    List<DfcfBanKuaiMaoLiLv> liLvs=   zhangTingBanService.queryZhangTingBanNew();
                    redisUtil.set(ZhangTingBanServiceImpl.ZHANG_TING_BAN_DATA,JSONObject.toJSONString(liLvs));
                }
            } catch (Exception e) {
                log.info("error = {}", e);
            }
            log.info("==========> 查询昨日成交额前100，今日的表现  TodayTrade50AmountTask end!");
        });

    }

    public void insertZhangTingBanData(String date) {
        if (StringUtils.isEmpty(date)) {
            date = HolidayCopy.getRealToday();
        }
        // HttpClient 超时配置
        RequestConfig globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD)
                .setConnectionRequestTimeout(6000).setConnectTimeout(6000).build();
        CloseableHttpClient httpClient = HttpClients.custom().setDefaultRequestConfig(globalConfig).build();
        ZhangTingBan zhangTingBan = new ZhangTingBan();
        zhangTingBan.setDate(date);
        zhangTingBan.setMinutes(HolidayCopy.getHHmmss().substring(8, 12));
        String htmlForStock = getHtmlStrByUrl(URL + date, httpClient, QueryZhangDieTingTask.USER_AGENT);
        htmlForStock = htmlForStock.replaceAll("callbackdata.+?\\(", "").split("\\);")[0];
        String pool = JsonPath.read(htmlForStock, "$.data.pool").toString();
        List<ZhangTingBanJson> list = JSONObject.parseArray(pool, ZhangTingBanJson.class);
        if (!CollectionUtils.isEmpty(list)) {
            ZhangTingBan deleteTemp = new ZhangTingBan();
            deleteTemp.setDate(zhangTingBan.getDate());
            zhangTingBanMapper.delete(deleteTemp);
            String finalDate = date;
            list.forEach(item -> {
                ZhangTingBan zhangTingBanTemp = new ZhangTingBan();
                BeanUtils.copyProperties(item, zhangTingBanTemp);
                zhangTingBanTemp.setDate(zhangTingBan.getDate());
                zhangTingBanTemp.setMinutes(zhangTingBan.getMinutes());
                zhangTingBanTemp.setCode(item.getC());
                zhangTingBanTemp.setName(item.getN());
                zhangTingBanTemp.setZttjDay(item.getZttj().getDays());
                zhangTingBanTemp.setZttjCt(item.getZttj().getCt());
                zhangTingBanTemp.setCreateTime(new Date());
                ZhangTingBan temp = new ZhangTingBan();
                temp.setDate(zhangTingBanTemp.getDate());
                //temp.setMinutes(zhangTingBanTemp.getMinutes());
                temp.setCode(zhangTingBanTemp.getCode());
                if (org.apache.commons.collections.CollectionUtils.isNotEmpty(zhangTingBanMapper.select(temp))) {
                    zhangTingBanMapper.delete(temp);
                }
                //获取涨停原因
                try {
                    KaiPanLa kaiPanLa;
                    String key = KaiPanLa.TODAY_ZHANG_TING + finalDate + zhangTingBanTemp.getCode();
                    Object object = redisUtil.get(key);
                    if (null == object) {
                        Thread.sleep(1000);
                        kaiPanLa = getZhangTingReason(zhangTingBanTemp.getCode().replace("sh", "").replace("sz", ""));
                        log.info("读取第三方：code={}，result={}",zhangTingBanTemp.getCode(),JSONObject.toJSONString(kaiPanLa));
                        redisUtil.set(key, kaiPanLa,60*60*24);
                    } else {
                        kaiPanLa = (KaiPanLa) object;
                        log.info("读取缓存：code={}，result={}",zhangTingBanTemp.getCode(),JSONObject.toJSONString(kaiPanLa));
                    }
                    if (null != kaiPanLa) {
                        if(!CollectionUtils.isEmpty(kaiPanLa.getList())){
                            StringBuffer str = new StringBuffer("【").append(kaiPanLa.getList().get(0).getSCLT()).append("】").append(kaiPanLa.getList().get(0).getGNSM());
                            zhangTingBanTemp.setZtReason(str.toString());
                        }else{

                        }
                    }
                } catch (Exception e) {
                   log.error("开盘啦获取涨停原因出错：{}",e);
                }
                //获取PE
                try {
                    CompanyCodeInfo companyCodeInfo = companyCodeInfoService.getInfoByStockName(zhangTingBanTemp.getCode());
                    if (null != companyCodeInfo) {
                        zhangTingBanTemp.setPe(companyCodeInfo.getPe());
                    }
                } catch (Exception e) {
                    log.error("开盘啦获取涨停原因出错：{}",e);
                }
                zhangTingBanMapper.insert(zhangTingBanTemp);
            });
        }
    }

    public static String getHtmlStrByUrl(String url, CloseableHttpClient httpClient, String USER_AGENT) {
        HttpGet httpGetForFName = new HttpGet(url);
        httpGetForFName.addHeader("User-Agent", USER_AGENT);
        //  httpGetForFName.addHeader("Cookie", getCOOKIE());
        httpGetForFName.addHeader("Content-Type", "text/html; charset=utf-8");
        httpGetForFName.addHeader("Accept-Encoding", "gzip, deflate");
        httpGetForFName.addHeader("Connection", "keep-alive");
        // 发送请求，并执行
        CloseableHttpResponse response;
        String html = "";
        try {
            response = httpClient.execute(httpGetForFName);
            // response植入cookie
            Header[] ssoResponseHeader = response.getHeaders("Set-Cookie");
            InputStream in = response.getEntity().getContent();
            html = convertStreamToString(in);

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return html;
    }

    public static String convertStreamToString(InputStream in) {
        StringBuilder sb = new StringBuilder();
        try {

            InputStreamReader isr = new InputStreamReader(in, "utf-8");
            BufferedReader reader = new BufferedReader(isr);
            String line = null;
            while ((line = reader.readLine()) != null) {
                sb.append(line + "/n");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();

    }

    /**
     *
     */
    public void chengJiaoECache(){
        //涨停原因-缓存
        try {
            List<DfcfBanKuaiMaoLiLv> dfcfBanKuaiMaoLiLvList= indexService.chengJiaoE();
            //看点
            initKanDian(dfcfBanKuaiMaoLiLvList,Boolean.TRUE);

            //30 Min 成交额
            getTrade30MinutesVol(dfcfBanKuaiMaoLiLvList);
            //Catche
            String str=JSONObject.toJSONString(dfcfBanKuaiMaoLiLvList);
            redisUtil.set(IndexServiceImpl.STOCK_TRADE_SUM,str);
        }catch (Exception e){
            log.error("{}",e);
        }
    }
    public void getTrade30MinutesVol(List<DfcfBanKuaiMaoLiLv> dfcfBanKuaiMaoLiLvList) {
        dfcfBanKuaiMaoLiLvList.forEach(item -> {
            BigDecimal today30MinVol = BigDecimal.ZERO;
            BigDecimal yesToday30MinVol = BigDecimal.ZERO;
            List<String> days = Lists.newArrayList();
            List<BigDecimal> vols = companyStockMinutesService.getTrade30MinutesVol(item.getCode(), days);
            //
            if (org.apache.commons.collections.CollectionUtils.isNotEmpty(vols)) {
                today30MinVol = vols.get(vols.size() - 1);
                yesToday30MinVol = vols.get(vols.size() - 2);
            }
            item.setTradeVol30Min(today30MinVol);
            item.setYesTodayTradeVol30Min(yesToday30MinVol);
            if(item.getYesTodayTradeVol30Min().compareTo(BigDecimal.ZERO)==1){
                item.setLiangBi(item.getTradeVol30Min().divide(item.getYesTodayTradeVol30Min(),2,BigDecimal.ROUND_HALF_UP));
            }else{
                item.setLiangBi(BigDecimal.ZERO);
            }
        });
    }


    /**
     * 涨停原因-缓存
     * @param dfcfBanKuaiMaoLiLvList
     */
    public void initKanDian(List<DfcfBanKuaiMaoLiLv> dfcfBanKuaiMaoLiLvList,Boolean isCache){
        dfcfBanKuaiMaoLiLvList.stream().forEach(item-> {
            try {
                KaiPanLa kaiPanLa;
                String key = KaiPanLa.TODAY_ZHANG_TING + HolidayCopy.getRealToday() +"_"+ item.getCode();
                Object object = redisUtil.get(key);
                if (null == object) {
                    Thread.sleep(1000);
                    kaiPanLa = getGetDayZhangTing(item.getCode().replace("sh", "").replace("sz", ""));
                    log.info("读取第三方：code={}，result={}", item.getCode(), JSONObject.toJSONString(kaiPanLa));
                    redisUtil.set(key, kaiPanLa);
                } else {
                    kaiPanLa = (KaiPanLa) object;
                    log.info("读取缓存：code={}，result={}", item.getCode(), JSONObject.toJSONString(kaiPanLa));
                }
                if (null != kaiPanLa) {
                    if (!CollectionUtils.isEmpty(kaiPanLa.getList())) {
                        StringBuffer str = new StringBuffer("【").append(kaiPanLa.getList().get(0).getSCLT()).append("】").append(kaiPanLa.getList().get(0).getGNSM());
                        ThsGeGuReZDian thsGeGuReZDian = null;
                        List<ThsGeGuReZDian> kanDian = item.getKanDian();
                        for (ThsGeGuReZDian thsGeGuReZDian1 : kanDian) {
                            List<ThsGeGuReZDian> kanDianTagName=  kanDian.stream().filter(a -> "历史涨停原因".equals(thsGeGuReZDian1.getTagName())).collect(Collectors.toList());
                            if(!CollectionUtils.isEmpty(kanDianTagName)&&kanDianTagName.size()>0){
                                continue;
                            }
                            if ("历史涨停原因".equals(thsGeGuReZDian1.getTagName())) {
                                thsGeGuReZDian1.setZtDesc(str.toString());
                                continue;
                            } else {
                                thsGeGuReZDian = new ThsGeGuReZDian();
                                thsGeGuReZDian.setTagName("历史涨停原因");
                                thsGeGuReZDian.setZtDesc(str.toString());
                                continue;
                            }
                        }
                        if (null != thsGeGuReZDian) {
                            item.getKanDian().add(thsGeGuReZDian);
                        }
                    }
                }

                //查询概念
                KaiPanLaZhangTingInfo kaiPanLaZhangTingInfo = kaiPanLaZhangTingInfoMapper.queyByCode(item.getCode().replace("sh", "").replace("sz", ""));
                if (null != kaiPanLaZhangTingInfo) {
                    item.setBk(kaiPanLaZhangTingInfo.getZyglbk());
                    item.setZhangTingId(kaiPanLaZhangTingInfo.getId());
                }else{
                    item.setBk("-");
                    item.setZhangTingId(0L);
                }
            } catch (Exception e) {
                log.error("开盘啦获取涨停原因出错：{}", e);
            }
        });


        //只看公司印象
        {
            dfcfBanKuaiMaoLiLvList.forEach(item -> {
                List<ThsGeGuReZDian> kanDianNew = Lists.newArrayList();
                List<ThsGeGuReZDian> kanDian = item.getKanDian();
                for (ThsGeGuReZDian thsGeGuReZDian1 : kanDian) {
                    if ("历史涨停原因".equals(thsGeGuReZDian1.getTagName())||"市场印象".equals(thsGeGuReZDian1.getTagName())) {
                        kanDianNew.add(thsGeGuReZDian1);
                    }
                }
                item.setKanDian(kanDianNew);
            });
        }
    }

    /**
     * 查询当天
     * @param code
     * @return
     * @throws Exception
     */
    public static KaiPanLa getZhangTingReason(String code) throws Exception {
        List<NameValuePair> nameValuePairList= Lists.newArrayList();
        nameValuePairList.add(new BasicNameValuePair("PhoneOSNew", "2"));
        nameValuePairList.add(new BasicNameValuePair("StockID", code));
        nameValuePairList.add(new BasicNameValuePair("VerSion", "5.4.0.0"));
        nameValuePairList.add(new BasicNameValuePair("apiv", "w29"));
        nameValuePairList.add(new BasicNameValuePair("a", "GetKLineZhangTing"));
        nameValuePairList.add(new BasicNameValuePair("c", "StockLineData"));
        Object str = HttpClientService.sendPost("https://apphq.longhuvip.com/w1/api/index.php", nameValuePairList);
        if(null!=str){
            KaiPanLa kaiPanLa=JSONObject.parseObject(JSONObject.toJSONString(str),KaiPanLa.class);
          return kaiPanLa;
        }
        return null;
    }

    /**
     * 查询历史
     * @param code
     * @return
     * @throws Exception
     */
    public static KaiPanLa getGetDayZhangTing(String code) throws Exception {
        List<NameValuePair> nameValuePairList= Lists.newArrayList();
        nameValuePairList.add(new BasicNameValuePair("Index", "0"));
        nameValuePairList.add(new BasicNameValuePair("PhoneOSNew", "2"));
        nameValuePairList.add(new BasicNameValuePair("StockID", code));
        nameValuePairList.add(new BasicNameValuePair("VerSion", "5.4.0.0"));
        nameValuePairList.add(new BasicNameValuePair("apiv", "w29"));
        nameValuePairList.add(new BasicNameValuePair("a", "GetDayZhangTing"));
        nameValuePairList.add(new BasicNameValuePair("c", "HisLimitResumption"));
        nameValuePairList.add(new BasicNameValuePair("st", "20"));
        Object str = HttpClientService.sendPost("https://apphis.longhuvip.com/w1/api/index.php", nameValuePairList);
        if(null!=str){
            KaiPanLa kaiPanLa=JSONObject.parseObject(JSONObject.toJSONString(str),KaiPanLa.class);
            return kaiPanLa;
        }
        return null;
    }
}
